package com.sikaryofficial.backend.service.statistics;

import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.sikaryofficial.backend.constant.MyStatisticsTypeEnum;
import com.sikaryofficial.backend.domain.entity.MyStatistics;
import com.sikaryofficial.backend.service.IMyStatisticsService;
import com.sikaryofficial.backend.service.article.cache.ArticleCacheService;
import com.sikaryofficial.backend.service.brand.cache.BrandTasteCacheService;
import com.sikaryofficial.system.api.model.product.BrandTasteDTO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.Objects;
import java.util.Optional;

/**
 * @author : qinjinyuan
 * @desc : 我的统计监听类
 * @date : 2023/11/01 17:29
 */
@Component
@Slf4j
public class MyStatisticsProcessor {

    @Autowired
    private IMyStatisticsService myStatisticsService;

    @Autowired
    private BrandTasteCacheService brandTasteCacheService;
    @Autowired
    private ArticleCacheService articleCacheService;

    /**
     * 新增统计数量
     *
     * @param event
     */
    public void addMyStatistics(MyStatisticsEvent event) {
        if (Objects.isNull(event.getUserId()) || Objects.equals(event.getUserId(), 0L)) {
            return;
        }
        /**
         * 查询数据，如果数据存在，则进行数量加一
         * 如果不存在，则创建数据
         */
        MyStatistics currentStatistics = myStatisticsService.getOne(new LambdaUpdateWrapper<MyStatistics>()
                .eq(MyStatistics::getCreatedBy, event.getUserId())
                .eq(MyStatistics::getDeletedVersion, 0L)
                .eq(MyStatistics::getBusinessType, event.getBusinessType())
                .eq(MyStatistics::getObjectId, event.getObjectId())
                .last(" limit 1"));
        if (Objects.isNull(currentStatistics)) {
            MyStatistics saveEntity = MyStatistics.builder()
                    .businessNum(1L)
                    .businessType(event.getBusinessType())
                    .objectId(event.getObjectId())
                    .createdBy(event.getUserId())
                    .createdTime(new Date())
                    .build();
            myStatisticsService.save(saveEntity);
        } else {
            // 是否累加计数
            boolean countUp = MyStatisticsTypeEnum.getEnum(event.getBusinessType()).getHasCountUp();
            myStatisticsService.update(new LambdaUpdateWrapper<MyStatistics>()
                    .set(MyStatistics::getBusinessNum, countUp ? currentStatistics.getBusinessNum() + 1 : 1L)
                    .set(MyStatistics::getUpdatedBy, event.getUserId())
                    .set(MyStatistics::getUpdatedTime, new Date())
                    .eq(MyStatistics::getDeletedVersion, 0L)
                    .eq(MyStatistics::getMyStatisticsId, currentStatistics.getMyStatisticsId())
            );
        }
        // 缓存数据更新
        updateCache(event.getBusinessType(), event.getObjectId());
    }

    /**
     * 缓存数据更新
     *
     * @param businessType
     * @param objectId
     */
    private void updateCache(Integer businessType, Long objectId) {
        // 产品
        if (MyStatisticsTypeEnum.COMMENTS_PRODUCT_COUNT == MyStatisticsTypeEnum.getEnum(businessType)) {
            BrandTasteDTO brandTasteDTO = brandTasteCacheService.getSignBrandTaste(objectId);
            if (Objects.nonNull(brandTasteDTO)) {
                // 产品对应的评价数量
                brandTasteDTO.setEvaluationCount(brandTasteDTO.getEvaluationCount() + 1);
                brandTasteCacheService.updateBrandTasteCacheOnly(brandTasteDTO);
            }
        }
    }

    /**
     * 新增统计数量 (手动设置租户ID)
     *
     * @param event
     */
    public void addMyStatisticsWithTenant(MyStatisticsWithTenantEvent event) {
        /**
         * 查询数据，如果数据存在，则进行数量加一
         * 如果不存在，则创建数据
         */
        MyStatistics currentStatistics = myStatisticsService.getOne(new LambdaUpdateWrapper<MyStatistics>()
                .eq(MyStatistics::getCreatedBy, event.getUserId())
                .eq(MyStatistics::getDeletedVersion, 0L)
                .eq(MyStatistics::getBusinessType, event.getBusinessType())
                .eq(MyStatistics::getObjectId, event.getObjectId())
                .eq(MyStatistics::getTenantId, event.getTenantId())
                .last(" limit 1"));
        if (Objects.isNull(currentStatistics)) {
            MyStatistics saveEntity = MyStatistics.builder()
                    .businessNum(1L)
                    .tenantId(event.getTenantId())
                    .businessType(event.getBusinessType())
                    .objectId(event.getObjectId())
                    .createdBy(event.getUserId())
                    .createdTime(new Date())
                    .build();
            myStatisticsService.save(saveEntity);
        } else {
            // 是否累加计数
            boolean countUp = MyStatisticsTypeEnum.getEnum(event.getBusinessType()).getHasCountUp();
            myStatisticsService.update(new LambdaUpdateWrapper<MyStatistics>()
                    .set(MyStatistics::getBusinessNum, countUp ? currentStatistics.getBusinessNum() + 1 : 1L)
                    .set(MyStatistics::getUpdatedBy, event.getUserId())
                    .set(MyStatistics::getUpdatedTime, new Date())
                    .eq(MyStatistics::getTenantId, event.getTenantId())
                    .eq(MyStatistics::getDeletedVersion, 0L)
                    .eq(MyStatistics::getMyStatisticsId, currentStatistics.getMyStatisticsId())
            );
        }
        // 缓存数据更新
        updateCache(event.getBusinessType(), event.getObjectId());
    }

    /**
     * 减少统计数量
     *
     * @param event
     */
    @EventListener
    public void reduceMyStatistics(MyStatisticsEvent event) {
        // 是否减少计数
        boolean hasReduce = MyStatisticsTypeEnum.getEnum(event.getBusinessType()).getHasReduce();
        if (!hasReduce) {
            log.info("不支持减少的业务类型");
            return;
        }
        /**
         * 查询数据，如果数据存在，则进行数量加一
         * 如果不存在，则创建数据
         */
        MyStatistics currentStatistics = myStatisticsService.getOne(new LambdaUpdateWrapper<MyStatistics>()
                .eq(MyStatistics::getCreatedBy, event.getUserId())
                .eq(MyStatistics::getBusinessType, event.getBusinessType())
                .eq(MyStatistics::getDeletedVersion, 0L)
                .eq(MyStatistics::getObjectId, event.getObjectId())
                .last(" limit 1"));

        // 什么情况下：删除
        Optional.ofNullable(currentStatistics).ifPresent(myStatistics -> myStatisticsService.update(
                new LambdaUpdateWrapper<MyStatistics>()
                        .set(MyStatistics::getUpdatedBy, event.getUserId())
                        .set(MyStatistics::getUpdatedTime, new Date())
                        .set(MyStatistics::getDeletedVersion, myStatistics.getMyStatisticsId())
                        .eq(MyStatistics::getMyStatisticsId, myStatistics.getMyStatisticsId())
                        .eq(MyStatistics::getCreatedBy, event.getUserId())
                        .eq(MyStatistics::getBusinessType, event.getBusinessType())
                        .eq(MyStatistics::getDeletedVersion, 0L)
                        .eq(MyStatistics::getObjectId, event.getObjectId())
        ));
    }
}
